package com.deyuanyun.pic.ctrl.service.impl;


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.deyuanyun.pic.business.controller.dto.PipeLineNewTaskVO;
import com.deyuanyun.pic.common.util.StringUtils;
import com.deyuanyun.pic.common.util.web.Asserts;
import com.deyuanyun.pic.ctrl.controller.dto.CathRepairRecodeDTO;
import com.deyuanyun.pic.ctrl.controller.dto.CathRepairTaskDTO;
import com.deyuanyun.pic.ctrl.controller.dto.CathRepairTaskQueryVO;
import com.deyuanyun.pic.ctrl.domain.CpRecRecode;
import com.deyuanyun.pic.ctrl.domain.CpRecRecodeExample;
import com.deyuanyun.pic.ctrl.domain.CpRecTask;
import com.deyuanyun.pic.ctrl.domain.CpRecTaskExample;
import com.deyuanyun.pic.ctrl.enumeration.DefectStateEnum;
import com.deyuanyun.pic.ctrl.enumeration.EqptTypeEnum;
import com.deyuanyun.pic.ctrl.mapper.CpRecRecodeMapper;
import com.deyuanyun.pic.ctrl.mapper.CpRecTaskMapper;
import com.deyuanyun.pic.ctrl.mapper.repair.CathRepairTaskExpandMapper;
import com.deyuanyun.pic.ctrl.service.CathRepairTaskService;
import com.deyuanyun.pic.ctrl.service.ExternalInspProjectService;
import com.deyuanyun.pic.settings.controller.pipe.vo.PipeLocationDTO;
import com.deyuanyun.pic.settings.domain.util.DomainInitUtil;
import com.deyuanyun.pic.settings.service.msgtemplate.PushMessage;
import com.deyuanyun.pic.settings.service.pipe.PipeLocationService;

@Service
public class CathRepairTaskServiceImpl implements CathRepairTaskService {
    
    private @Autowired CpRecTaskMapper repairTaskMapper;
    private @Autowired CpRecRecodeMapper cpRecRecodeMapper;
    private @Autowired CathRepairTaskExpandMapper repairTaskExpandMapper;
    private @Autowired PipeLocationService pipeLocationService;
    private @Autowired ExternalInspProjectService externalInspProjectService;
    
    
    //private @Autowired InsspSegmentMapper insspSegmentMapper;//检测管段的
    //private @Autowired DefectInfoService defectInfoService;//缺陷点信息Service
    
    private static final Logger logger = LoggerFactory.getLogger(CathRepairTaskServiceImpl.class);

    @Override
    public List<CpRecTask> queryRepairTaskList(CathRepairTaskQueryVO repairTaskVO){
        
        CpRecTaskExample example = new CpRecTaskExample();
        
        CpRecTaskExample.Criteria c = example.createCriteria();
        String pipeLineId = repairTaskVO.getPipeLineId();
        if(StringUtils.isNotEmpty(pipeLineId)){//条件查询管道
            c.andPipeLineIdEqualTo(repairTaskVO.getPipeLineId());
        }
        
        Long beginMileage = repairTaskVO.getBeginMileage();//起始绝对距离
        if(beginMileage != null){
            c.andFromPointMileageGreaterThanOrEqualTo(beginMileage);
        }
        Long endMileage = repairTaskVO.getEndMileage();//终止绝对距离 
        if(endMileage != null){
            c.andToPointMileageLessThanOrEqualTo(endMileage);
        }
        
        String[] repairTaskIds = repairTaskVO.getRepairTaskIds();
        if(repairTaskIds != null && repairTaskIds.length > 0){//任务编号
            List<String> repairTaskIdList = new ArrayList<String>();
            Collections.addAll(repairTaskIdList, repairTaskIds);
            c.andIdIn(repairTaskIdList);
        }
        c.andDeletedEqualTo((short)0);
        example.setOrderByClause("create_date desc");
        List<CpRecTask> recTaskList = repairTaskMapper.selectByExample(example);
        
        //这个值拷贝效率是一个问题，用ASM、CGLIB来做呢，又显得复杂了。
        //List<CathRepairTaskDTO> cathRepairTaskList = new Page<CathRepairTaskDTO>();
        for (int i = 0; i < recTaskList.size(); i++) {
            CpRecTask cpRecTask = recTaskList.get(i);
            CathRepairTaskDTO cathRepairTask = new CathRepairTaskDTO();
            try {
                PropertyUtils.copyProperties(cathRepairTask, cpRecTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
            recTaskList.set(i, cathRepairTask);
            //cathRepairTaskList.add(cathRepairTask);
        }
        
        return recTaskList;
    }
    
    //填充起止点名称和绝对距离
    private void fillRepairTaskPointNameAndMileage(CpRecTask repairTask){
        
        String fromPointId = repairTask.getFromPointId();
        String endPointId = repairTask.getToPointId();
        String pipeLineId = repairTask.getPipeLineId();
        
        PipeLocationDTO pipeLocation1 = pipeLocationService.queryPipeLocationById(pipeLineId,fromPointId);
        repairTask.setFromPointMileage(pipeLocation1.getMileage2());
        
        PipeLocationDTO pipeLocation2 = pipeLocationService.queryPipeLocationById(pipeLineId,endPointId);
        repairTask.setToPointMileage(pipeLocation2.getMileage2());
    }
    
    
    
    @Override
    @PushMessage
    public void createOrUpdate(CpRecTask repairTask, CpRecRecode[] cpRecRecodes) {
        String rtId = repairTask.getId();
        if(StringUtils.isEmpty(rtId)){
            //repairTask.setRepairState(RepairTaskStatedEnum.WAIT_FOR_REPAIR.toString());//默认情况下新增进来就是待修复
            DomainInitUtil.initCreateDomain(repairTask);
            rtId = repairTask.getId();
            String dataStated = repairTask.getDataStated();
            if("20".equals(dataStated)){//如果是直接保存为已发布，保存时间也保存进去。
                //UserSessionVO sessionVO= SessionCacheSupport.getSessionVO();
                //String user = sessionVO.getUsername();
                //repairTask.setReleaseUser(user);
                //repairTask.setReleaseDate(new Date());
            }
            fillRepairTaskPointNameAndMileage(repairTask);//填充起止点名称和绝对距离
            
            logger.debug("创建阴保整改任务RepairTask>" + rtId);
            repairTaskMapper.insertSelective(repairTask);
            //
            
        }else{
            //判断一下，如果是已发布任务不能修改。
            CpRecTask repairTask_Old = selectByPrimaryKey(rtId);
            if(repairTask_Old != null){
                Asserts.assertTrue(!DefectStateEnum.state20.getCode().equals(repairTask_Old.getDataStated()), "已发布任务不能再次修改");
            }
            fillRepairTaskPointNameAndMileage(repairTask);//填充起止点名称和绝对距离
            logger.debug("更新阴保整改任务RepairTask>" + rtId);
            DomainInitUtil.initUpdateDomain(repairTask);
            repairTaskMapper.updateByPrimaryKeySelective(repairTask);
            
            if(cpRecRecodes != null){
                //修改阴保整改任务时，把原有的整改设备全部去掉。
                List<CpRecRecode> cpRecRecodeList = queryRepairRecodeList(rtId,null);
                for (int i = 0; i < cpRecRecodeList.size(); i++) {
                    String id = cpRecRecodeList.get(i).getId();
                    cpRecRecodeMapper.deleteByPrimaryKey(id);
                }
            }
        }
        if(cpRecRecodes != null){
            for (int i = 0; i < cpRecRecodes.length; i++) {
                CpRecRecode cpRecRecode = cpRecRecodes[i];
                cpRecRecode.setRecTaskId(rtId);
                DomainInitUtil.initCreateDomain(cpRecRecode);
                cpRecRecodeMapper.insertSelective(cpRecRecode);
            }   
        }
        
        
    }
    
    
    @Override
    public void createOrUpdateRecord(String repairTaskId, CpRecRecode[] cpRecRecodes) {
        //修改阴保整改任务时，把原有的整改记录全部去掉。
        List<CpRecRecode> cpRecRecodeList = queryRepairRecodeList(repairTaskId,null);
        
        for (int j = 0; j < cpRecRecodes.length; j++) {
            CpRecRecode cpRecRecode = cpRecRecodes[j];
            //cpRecRecode.setRecTaskId(repairTaskId);
            String eQPTType2 = cpRecRecode.getEqptType();
            String eQPTId2 = cpRecRecode.getEqptNumber();
            
            for (int i = 0; i < cpRecRecodeList.size(); i++) {
                CpRecRecode cathRepairRecode = cpRecRecodeList.get(i);
                String id = cathRepairRecode.getId();
                String eQPTType1 = cathRepairRecode.getEqptType();
                String eQPTId1 = cathRepairRecode.getEqptNumber();
                if(eQPTType1.equals(eQPTType2) && eQPTId1.equals(eQPTId2)){//设备类型和设备编号相同，就替换
                    cpRecRecode.setId(id);//ID
                    //维修建议、最迟维修时间、检测单位、检测日期.........不修改。
                    DomainInitUtil.initUpdateDomain(cpRecRecode);
                    cpRecRecodeMapper.updateByPrimaryKeySelective(cpRecRecode);
                    cpRecRecodeList.remove(i);
                    i--;
                    break;
                }else{
                    Asserts.assertTrue(i < cpRecRecodeList.size() - 1, "没有在该任务下找到设备：" + eQPTId2);
                }
            }
        }
        //去掉本次未导入的整改设备的整改记录
        for (int i = 0; i < cpRecRecodeList.size(); i++) {
            CpRecRecode cathRepairRecode = cpRecRecodeList.get(i);
            cathRepairRecode.setRectificationCompany(null);//整改单位
            cathRepairRecode.setRectificationDate(null);//整改日期
            cathRepairRecode.setRectificationDescription(null);//整改记录
            cathRepairRecode.setMileage(null);//绝对距离
            repairTaskExpandMapper.updateRecRecodeByPrimaryKey(cathRepairRecode);
        }
        
        CpRecTask cpRecTask = new CpRecTask();//repairTaskMapper.selectByPrimaryKey(repairTaskId);
        cpRecTask.setDataStated("20");
        cpRecTask.setId(repairTaskId);
        DomainInitUtil.initUpdateDomain(cpRecTask, "已导入整改记录");
        repairTaskMapper.updateByPrimaryKeySelective(cpRecTask);
    }

    @Override
    public int updateToDelete(String[] rtIds) {
        int secc = 0;//返回成功数量
        for (int i = 0; i < rtIds.length; i++) {
            String rtId = rtIds[i];
            
            CpRecTask repairTask_Old = selectByPrimaryKey(rtId);
            if(repairTask_Old == null){
                continue;
            }
            if(DefectStateEnum.state20.getCode().equals(repairTask_Old.getDataStated())){
                logger.debug("已发布的阴保整改任务不能删除>" + rtId);
                continue;
            }
            
            CpRecTask repairTask = new CpRecTask();
            repairTask.setId(rtId);
            repairTask.setDeleted((short)1);
            DomainInitUtil.initUpdateDomain(repairTask,"删除任务");
            secc += updateByPrimaryKeySelective(repairTask);
            //TODO 待处理：删除阴保整改任务的时候，缺陷点的WAIT_FOR_REPAIR应当置为NULL
            //清除pic_tdf_defect_info表中的REPAIR_TASK_ID置为NULL.....
            //repairTaskExpandMapper.updateDefectInfoRepairTaskIdToNull(rtId);
        }
        return secc;
    }

    @Override
    public List<CpRecRecode> queryRepairRecodeList(String repairTaskId,EqptTypeEnum eqptTypeEnum) {
        
        CpRecRecodeExample example = new CpRecRecodeExample();
        CpRecRecodeExample.Criteria c = example.createCriteria().andRecTaskIdEqualTo(repairTaskId);
        if(eqptTypeEnum != null){
            c.andEqptTypeEqualTo(eqptTypeEnum.toString());
        }
        List<CpRecRecode> cpRecRecodeList = cpRecRecodeMapper.selectByExample(example);
        
        //这个值拷贝效率是一个问题，用ASM、CGLIB来做呢，又显得复杂了。
        //List<CathRepairRecodeDTO> cathRepairRecodeList = new ArrayList<CathRepairRecodeDTO>(cpRecRecodeList.size());
        for (int i = 0 ; i < cpRecRecodeList.size() ; i++) {
            CpRecRecode cpRecRecode = cpRecRecodeList.get(i);
            CathRepairRecodeDTO cathRepairRecode = new CathRepairRecodeDTO();
            try {
                PropertyUtils.copyProperties(cathRepairRecode, cpRecRecode);
            } catch (Exception e) {
                e.printStackTrace();
            }
            cpRecRecodeList.set(i,cathRepairRecode);
        }
        return cpRecRecodeList;
    }

    
    
    @Override
    public List<Map<String, Object>> queryCathRepairTaskEffect( String repairTaskId, Date testingDate) {
        
        CathRepairTaskQueryVO repairTaskVO = new CathRepairTaskQueryVO();
        repairTaskVO.setRepairTaskIds(new String[]{repairTaskId});
        List<CpRecTask> recTaskList = queryRepairTaskList(repairTaskVO);
        Asserts.assertTrue(recTaskList != null && !recTaskList.isEmpty(), "没有找到这个整改任务");
        CpRecTask recTask = recTaskList.get(0);
        Date date = recTask.getPlanStartDate();
        /*
        String pipeLineId = recTask.getPipeLineId();
        
        Long beginMileage = recTask.getFromPointMileage();
        Long endMileage = recTask.getToPointMileage();
        */
        
        /*
        List<PipeLineNewTaskVO> pipeLineNewTaskList1 = externalInspProjectService.queryNagmExternalTaskMerge(pipeLineId, date, true);
        List<PipeLineNewTaskVO> pipeLineNewTaskList2 = externalInspProjectService.queryNagmExternalTaskMerge(pipeLineId, testingDate, false);
        
        if(pipeLineNewTaskList1 == null || pipeLineNewTaskList1.isEmpty()){
            return Collections.emptyList();
        }
        */
        List<Map<String, Object>> list = repairTaskExpandMapper.queryCathRepairTaskEffect(repairTaskId, date, testingDate);
        
        return list;
    }

    public CpRecTask selectByPrimaryKey(String id) {
        return this.repairTaskMapper.selectByPrimaryKey(id);
    }

    public int deleteByPrimaryKey(String id) {
        return this.repairTaskMapper.deleteByPrimaryKey(id);
    }

    public int updateByPrimaryKeySelective(CpRecTask record) {
        return this.repairTaskMapper.updateByPrimaryKeySelective(record);
    }

    public int updateByPrimaryKey(CpRecTask record) {
        return this.repairTaskMapper.updateByPrimaryKey(record);
    }

    public int insert(CpRecTask record) {
        return this.repairTaskMapper.insert(record);
    }
}